package com.tanhua.server.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.UserFreezeMapper;
import com.tanhua.common.pojo.UserFreeze;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.server.api.LogApi;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.server.vo.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.server.vo.UserInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class UserService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Reference
    private UserLikeApi userLikeApi;

    @Reference
    private LogApi logApi;

    @Autowired
    private UserFreezeMapper userFreezeMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private final String REDIS_FREEZE_USER = "REDIS_FREEZE_USER";
    private final String REDIS_FREEZE_USER_ID = "REDIS_FREEZE_USER_ID_";

    /**
     * 根据条件查询用户信息列表
     *
     * @param page     (必须)当前页
     * @param pagesize (必须)每页页数
     * @param userId   (非必须)用户id
     * @param nickName (非必须)用户昵称
     * @param city     (非必须)城市
     * @return
     */
    public PageResult usersList(Integer page, Integer pagesize, Integer userId, String nickName, String city) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        //根据page,pagesize进行分页查询
        IPage<UserInfo> pageRequest = new Page<>(page - 1, pagesize);

        if (ObjectUtil.isAllNotEmpty(userId, nickName, city)) {
            //根据(用户id,用户昵称,用户注册城市)条件进行查询
            wrapper.eq(UserInfo::getUserId, userId)
                    .and(q -> q.like(UserInfo::getNickName, nickName)
                            .and(q1 -> q1.like(UserInfo::getCity, city)));
        } else if (ObjectUtil.isAllNotEmpty(userId, nickName)) {
            //根据(用户id,用户昵称)条件进行查询
            wrapper.eq(UserInfo::getUserId, userId)
                    .and(q -> q.like(UserInfo::getNickName, nickName));
        } else if (ObjectUtil.isAllNotEmpty(userId, city)) {
            //根据(用户id,用户注册城市)条件进行查询
            wrapper.eq(UserInfo::getUserId, userId)
                    .and(q -> q.like(UserInfo::getCity, city));
        } else if (ObjectUtil.isAllNotEmpty(nickName, city)) {
            //根据(用户昵称,用户注册城市)条件进行查询
            wrapper.like(UserInfo::getNickName, nickName)
                    .and(q -> q.like(UserInfo::getCity, city));
        } else if (ObjectUtil.isNotEmpty(userId)) {
            //根据(用户id)条件进行查询
            wrapper.eq(UserInfo::getUserId, userId);
        } else if (ObjectUtil.isNotEmpty(nickName)) {
            //根据(用户昵称)条件进行查询
            wrapper.like(UserInfo::getNickName, nickName);
        } else if (ObjectUtil.isNotEmpty(city)) {
            //根据(用户注册城市)条件进行查询
            wrapper.like(UserInfo::getCity, city);
        }

        IPage<UserInfo> userInfoIPage = userInfoMapper.selectPage(pageRequest, wrapper);
        //总记录数
        long total = userInfoIPage.getTotal();
        //总页数
        long pages = userInfoIPage.getPages();
        List<UserInfo> userInfoList = userInfoIPage.getRecords();

        List<UserInfoVo> list = new ArrayList<>();
        //封装用户信息
        for (UserInfo userInfo : userInfoList) {
            UserInfoVo userInfoVo = new UserInfoVo();
            //根据userInfo查询用户id
            //根据查询到的用户id,得到user对象
            Long id = userInfo.getUserId();
            LambdaQueryWrapper<User> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(User::getId, id);
            User user = userMapper.selectOne(wrapper1);

            //封装userInfoVo中的数据
            userInfoVo.setId(Convert.toInt(userInfo.getUserId()));//用户id
            userInfoVo.setLogo(userInfo.getLogo());//头像
            userInfoVo.setLogoStatus(Convert.toStr(userInfo.getLogoStatus()));//头像状态,1通过,2拒绝
            userInfoVo.setNickname(userInfo.getNickName());//昵称
            userInfoVo.setMobile(user.getMobile());//手机号
            userInfoVo.setSex(userInfo.getSex().getValue() == 1 ? "男" : "女");//性别
            userInfoVo.setAge(userInfo.getAge());//年龄
            userInfoVo.setOccupation(userInfo.getOccupation());//职业
            userInfoVo.setUserStatus(userInfo.getUserStatus() == 1 ? "1" : "2");//用户状态,1正常,2冻结
            userInfoVo.setLastActiveTime(new Date(logApi.queryUserLogTime(Convert.toLong(user.getId()))));//最近活跃时间 TODO
            userInfoVo.setCity(userInfo.getCity());//注册城市名称

            //将用户信息添加到list集合
            list.add(userInfoVo);
        }

        //如果查询数据为空
        //使用UserManagerVo实体类封装数据返回
        /*if (ObjectUtil.isEmpty(list)) {
        }*/
        //查询数据不为空
        //使用PageResult实体类封装数据返回
        PageResult result = new PageResult();
        result.setPages(Convert.toInt(pages));
        result.setCounts(Convert.toInt(total));
        result.setPage(page);
        result.setPagesize(pagesize);
        result.setItems(list);
        return result;
    }

    /**
     * 根据用户id查询用户信息
     *
     * @param userId
     * @return
     */
    public UserInfoVo findUserInfoById(Integer userId) {
        //根据userId查询mysql中的User表
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId, userId);
        User user = userMapper.selectOne(wrapper);

        //根据userId查询mysql中的UserInfo表
        LambdaQueryWrapper<UserInfo> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(UserInfo::getUserId, userId);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper1);

        //查询喜欢数,被喜欢数,匹配人数
        Long likeCount = userLikeApi.queryMyLikeUserCount(Convert.toLong(userId));
        Long beLikeCount = userLikeApi.queryLikeMeUserCount(Convert.toLong(userId));
        Long mutualLikeCount = userLikeApi.mutualLikeUserCount(Convert.toLong(userId));

        //封装用户信息  userInfoVo
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setId(userId);//用户id
        userInfoVo.setLogo(userInfo.getLogo());//头像
        userInfoVo.setLogoStatus(Convert.toStr(userInfo.getLogoStatus()));//头像状态
        userInfoVo.setNickname(userInfo.getNickName());//昵称
        userInfoVo.setMobile(user.getMobile());//手机号
        userInfoVo.setSex(userInfo.getSex().getValue() == 1 ? "男" : "女");//性别
        userInfoVo.setAge(userInfo.getAge());//年龄
        userInfoVo.setOccupation(userInfo.getOccupation());//职业
        userInfoVo.setIncome(Convert.toInt(userInfo.getIncome()));//收入
        userInfoVo.setUserStatus(userInfo.getUserStatus() == 1 ? "1" : "2");//用户状态
        userInfoVo.setLastActiveTime(new Date(logApi.queryUserLogTime(Convert.toLong(userId))));//最近活跃时间
        userInfoVo.setCity(userInfo.getCity());//注册城市名称
        userInfoVo.setPersonalSignature(userInfo.getPersonalSignature());//个性签名
        userInfoVo.setCountBeLiked(Convert.toInt(likeCount));//被喜欢人数
        userInfoVo.setCountLiked(Convert.toInt(beLikeCount));//喜欢人数
        userInfoVo.setCountMatching(Convert.toInt(mutualLikeCount));//匹配人数
        userInfoVo.setLastLoginLocation(logApi.queryUserLocation(Convert.toLong(userId)));//最近登录地
        userInfoVo.setTags(userInfo.getTags());//用户标签
        userInfoVo.setCreated(userInfo.getCreated());//注册时间

        return userInfoVo;
    }

    /**
     * 用户冻结操作
     *
     * @param params
     * @return
     */
    public String freeze(Map<String, Object> params) {
        //1.获取参数
        Integer userId = Convert.toInt(params.get("userId"));//用户id
        Integer freezingTime = Convert.toInt(params.get("freezingTime"));//冻结时间
        Integer freezingRange = Convert.toInt(params.get("freezingRange"));//冻结范围
        String reasonsForFreezing = Convert.toStr(params.get("reasonsForFreezing"));//冻结原因
        String frozenRemarks = Convert.toStr(params.get("frozenRemarks"));//冻结备注

        //将当前冻结用户id存入Redis中的(集合名REDIS_FREEZE_USER_ID)Hash集合中
        Long freezeDeadlineMillisecond = 0L;
        if (freezingTime == 1) {
            //冻结三天
            freezeDeadlineMillisecond = 3 * 24 * 3600 * 1000L;
        } else if (freezingTime == 2) {
            //冻结七天
            freezeDeadlineMillisecond = 7 * 24 * 3600 * 1000L;
        } else if (freezingTime == 3) {
            //冻结永久
            freezeDeadlineMillisecond = 100 * 365 * 24 * 3600 * 1000L;
        }
        Date date = new Date(freezeDeadlineMillisecond);
        System.out.println(date);
        redisTemplate.opsForHash().put(REDIS_FREEZE_USER, REDIS_FREEZE_USER_ID + userId, Convert.toStr(System.currentTimeMillis() + freezeDeadlineMillisecond));

        //2.封装数据
        UserInfo userInfo = new UserInfo();
        //封装UserFreeze对象
        UserFreeze userFreeze = new UserFreeze();
        userFreeze.setUserId(userId);
        userFreeze.setFreezingTime(freezingTime);
        userFreeze.setFreezingRange(freezingRange);
        userFreeze.setReasonsForFreezing(reasonsForFreezing);
        userFreeze.setFrozenRemarks(frozenRemarks);
        userFreeze.setExpireDate(new Date(freezeDeadlineMillisecond + System.currentTimeMillis()));
        userFreeze.setCreated(new Date());

        /**
         *  3.判断tb_user_freeze表是否已存在改用户记录:
         *      不存在,在tb_user_freeze表新增该用户冻结信息
         *      存在,在tb_user_freeze表更新该用户冻结信息
         */
        //3.1根据用户id查询在tb_user_freeze表是否存在该用户
        LambdaQueryWrapper<UserFreeze> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserFreeze::getUserId, userId);
        UserFreeze userFreeze1 = userFreezeMapper.selectOne(wrapper);
        if (ObjectUtil.isEmpty(userFreeze1)) {
            //3.2不存在,新增冻结信息
            userFreezeMapper.insert(userFreeze);
        } else {
            //3.3存在,更新冻结信息
            UpdateWrapper wrapper1 = new UpdateWrapper<>();
            wrapper1.eq("user_id", userId);
            userFreezeMapper.update(userFreeze, wrapper1);
        }

        //将用户状态由设置为:2(冻结)
        //封装UserInfo对象,更新tb_user_info表
        userInfo.setUserStatus(2);
        UpdateWrapper<UserInfo> wrapper1 = new UpdateWrapper<>();
        wrapper1.eq("user_id", userId);
        int i = userInfoMapper.update(userInfo, wrapper1);
        //4.判断是否成功冻结用户
        if (i == 1) {
            //4.1 冻结成功
            return "操作成功";
        }
        //4.2 冻结失败
        //提示后台: 冻结用户失败!!!
        throw new BusinessException(ErrorResult.freezeFail());
    }

    /**
     * 用户解冻操作
     *
     * @param params
     * @return
     */
    public String unfreeze(Map<String, Object> params) {
        //1.获取参数
        Integer userId = Convert.toInt(params.get("userId"));
        String reasonsForThawing = Convert.toStr(params.get("reasonsForThawing"));

        //将当前冻结用户id从Redis中的(集合名REDIS_FREEZE_USER_ID)Hash集合中删除
        redisTemplate.opsForHash().delete(REDIS_FREEZE_USER, REDIS_FREEZE_USER_ID + userId);

        //2.将参数封装成UserFreeze对象
        UserFreeze userFreeze = new UserFreeze();
        userFreeze.setReasonsForThawing(reasonsForThawing);
        //2.将参数封装成UserFreeze对象
        UserInfo userInfo = new UserInfo();
        //将用户状态设置为:1(正常)
        userInfo.setUserStatus(1);

        //3.更新tb_user_info表中的用户冻结信息
        UpdateWrapper wrapper1 = new UpdateWrapper<>();
        wrapper1.eq("user_id", userId);
        int i = userInfoMapper.update(userInfo, wrapper1);
        //更新tb_user_freeze表中的用户冻结信息
        UpdateWrapper<UserFreeze> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id", userId);
        userFreezeMapper.update(userFreeze, wrapper);

        //4.判断是否成功解冻用户
        if (i == 1) {
            //4.1 解冻成功
            return "操作成功";
        }
        //4.2 解冻失败
        //提示后台: 解冻用户失败!!!
        throw new BusinessException(ErrorResult.unfreezeFail());
    }
}
